package com.biao.test_annotation;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * 在spring中找到使用自定义注解的方法
 */

@Component
public class SpringUseDiyAnnotation implements ApplicationContextAware {

    @Autowired
    private ApplicationContext applicationContext;

    // 重写ApplicationContextAware 里面的方法
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public void getUseDiyAnnotationName() {
        // 通过applicationContext 获取所有bean对象的名称
        String[] beanNames = applicationContext.getBeanDefinitionNames();
        Arrays.stream(beanNames).forEach(name -> {
            // 拿到每个bean对象
            Class<?> aClass = applicationContext.getBean(name).getClass();
            // 拿到每个bean对象里面的所有方法
            Method[] methods = aClass.getMethods();
            Arrays.stream(methods).forEach(method -> {
                // 判断bean对象的每个方法里是否有使用到自定义注解 @InitMethod
                if (method.isAnnotationPresent(InitMethod.class)) {
                    try {
                        // 通过反射执行这个用到了自定义注解的方法
                        // 通过获取无参构造，获取实例，第二个参数args是方法的入参
                        method.invoke(aClass.getConstructor().newInstance(), null);
                        System.out.println("调用了加注解的方法。。。。。。");
                    } catch (IllegalAccessException | InvocationTargetException | InstantiationException |
                             NoSuchMethodException e) {
                        throw new RuntimeException(e);
                    }
                }
            });
        });
    }
}
